Skip to content

Conversation

cbeams
Copy link
Contributor

@cbeams cbeams commented Sep 6, 2011

Commit http://bit.ly/nXumTs ensured that component methods and fields
marked with 'common annotations' such as @resource, @PostConstruct and
@PreDestroy are invoked/assigned once and only once, even if multiple
instances of the CommonAnnotationBeanPostProcessor are processing the
same bean factory.

The implementation works against the InjectionMetadata API, adding and
removing these members from sets that track whether they are already
'externally managed', i.e. that another CABPP has already handled them,
thus avoiding redundant processing.

Prior to this change, the #remove operations against these sets were
not synchronized. In a single-threaded context this is fine thanks to
logic in AbstractAutowireCapableBeanFactory#doCreateBean that checks to
see whether a given bean definition has already been post processed.
However, as reported by SPR-8598, certain cases involving multiple
threads and annotated prototype-scoped beans can cause concurrent
modification exceptions during the #remove operation (ostensibly because
another thread is attempting to do the same removal at the same time,
though this has yet to be reproduced in isolation).

Now the sets originally introduced by the commit above are decorated
with Collections#synchronizedSet and any iterations over those sets
are synchronized properly. This change should have low performance
impact as such processing happens at container startup time (save for
non-singleton lookups at runtime), and there should be little
contention in any case.

Issue: SPR-8598

Commit http://bit.ly/nXumTs ensured that component methods and fields
marked with 'common annotations' such as @resource, @PostConstruct and
@PreDestroy are invoked/assigned once and only once, even if multiple
instances of the CommonAnnotationBeanPostProcessor are processing the
same bean factory.

The implementation works against the InjectionMetadata API, adding and
removing these members from sets that track whether they are already
'externally managed', i.e. that another CABPP has already handled them,
thus avoiding redundant processing.

Prior to this change, the #remove operations against these sets were
not synchronized. In a single-threaded context this is fine thanks to
logic in AbstractAutowireCapableBeanFactory#doCreateBean that checks to
see whether a given bean definition has already been post processed.
However, as reported by SPR-8598, certain cases involving multiple
threads and annotated prototype-scoped beans can cause concurrent
modification exceptions during the #remove operation (ostensibly because
another thread is attempting to do the same removal at the same time,
though this has yet to be reproduced in isolation).

Now the sets originally introduced by the commit above are decorated
with Collections#synchronizedSet and any iterations over those sets
are synchronized properly. This change should have low performance
impact as such processing happens at container startup time (save for
non-singleton lookups at runtime), and there should be little
contention in any case.

Issue: SPR-8598
@cbeams
Copy link
Contributor Author

cbeams commented Sep 12, 2011

Rebased these changes into subversion trunk after review with Juergen.

@cbeams cbeams closed this Sep 12, 2011
lks21c added a commit to lks21c/spring-framework-korean that referenced this pull request Jan 3, 2015
itcrazy0717 added a commit to itcrazy0717/spring-framework that referenced this pull request Jun 6, 2018
#1.对spring源码进行测试,在spring-context模块中添加测试代码
spring-projects#2.对spring的bean生命周期进行调试,具体代码在spring-context模块中
@itcrazy0717 itcrazy0717 mentioned this pull request Jun 6, 2018
This was referenced Jan 10, 2019
drodriguezhdez referenced this pull request in scope-demo/spring-framework Oct 14, 2019
cesarhernandezgt added a commit to cesarhernandezgt/spring-framework that referenced this pull request Mar 28, 2023
Ganeshgautam pushed a commit to atlassian-forks/spring-framework that referenced this pull request May 26, 2025
DCPL-1801 comment inaccesible urls for javadoc generation

Approved-by: Tom Rijnbeek
sbrannen added a commit that referenced this pull request Oct 22, 2025
Historically, @⁠Autowired fields in an enclosing class of a @⁠Nested
test class have been injected from the ApplicationContext for the
enclosing class. If the enclosing test class and @⁠Nested test class
share the same ApplicationContext configuration, things work as
developers expect. However, if the enclosing class and @⁠Nested test
class have different ApplicationContexts, that can lead to
difficult-to-debug scenarios. For example, a bean injected into the
enclosing test class will not participate in a test-managed transaction
in the @⁠Nested test class (see gh-34576).

JUnit Jupiter 5.12 introduced a new ExtensionContextScope feature which
allows the SpringExtension to behave the same for @⁠Autowired fields as
it already does for @⁠Autowired arguments in lifecycle and test
methods. Specifically, if a developer sets the ExtensionContextScope to
TEST_METHOD — for example, by configuring the following configuration
parameter as a JVM system property or in a `junit-platform.properties`
file — the SpringExtension already supports dependency injection from
the current, @⁠Nested ApplicationContext in @⁠Autowired fields in an
enclosing class of the @⁠Nested test class.

junit.jupiter.extensions.testinstantiation.extensioncontextscope.default=test_method

However, there are two scenarios that fail as of Spring Framework
6.2.12.

1. @⁠TestConstructor configuration in @⁠Nested class hierarchies.
2. Field injection for bean overrides (such as @⁠MockitoBean) in
   @⁠Nested class hierarchies.

Commit 82c34f7 fixed the SpringExtension to support scenario #2
above.

To fix scenario #1, this commit revises
BeanOverrideTestExecutionListener's injectField() implementation to
look up the fields to inject for the "current test instance" instead of
for the "current test class".

This commit also introduces tests for both scenarios.

See gh-34576
See gh-35676
Closes gh-35680
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant